home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 10 - Templates 89
- ______________________
-
- Do all three conditions need to be met for the linker to combine
- segments into one segment?
-
- 1) They have the same name
- 2) They have the same class name
- 3) They are both defined PUBLIC
-
- Joe Bob says check it out. Here are two .ASM files which contain
- a number of segments. Here's the first file:
-
- ;file1.asm
- ;- - - - - - - - - - - - - - - - - - - -
- STACKSEG SEGMENT STACK 'STACK'
- dw 100 dup (?)
- STACKSEG ENDS
- ;- - - - - - - - - - - - - - - - - - - -
- MORESTUFFA SEGMENT PUBLIC
- variable21 dw ?
- MORESTUFFA ENDS
- ;- - - - - - - - - - - - - - - - - - - -
- DATASTUFF SEGMENT PUBLIC 'DATA'
- variable1 dw ?
- DATASTUFF ENDS
- ;- - - - - - - - - - - - - - - - - - - -
- MORESTUFF SEGMENT PUBLIC 'DATA'
- variable2 dw ?
- MORESTUFF ENDS
- ;- - - - - - - - - - - - - - - - - - - -
- EVENMORESTUFF SEGMENT PUBLIC 'DATA'
- variable3 dw ?
- EVENMORESTUFF ENDS
- ;- - - - - - - - - - - - - - - - - - - -
- CODESTUFF SEGMENT PUBLIC 'CODE'
- ASSUME cs:CODESTUFF, ds:DATASTUFF
- ASSUME ds:MORESTUFF, es:MORESTUFFA, ds:EVENMORESTUFF
- main proc far
- start: push ds
- sub ax,ax
- push ax
- ret
- main endp
- CODESTUFF ENDS
- ;- - - - - - - - - - - - - - - - - - - -
- END start
-
- Here's the other file:
-
- ;file2.asm
- ; - - - - - - - - - - - - - - - - - - - -
- STACKSEG SEGMENT STACK 'STACK'
- dw 100 dup (?)
- STACKSEG ENDS
- ; - - - - - - - - - - - - - - - - - - - -
- NOTDATASTUFF SEGMENT PUBLIC 'DATA'
- variable4 dw ?
- NOTDATASTUFF ENDS
- ; - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- The PC Assembler Tutor 90
- ______________________
-
- DATASTUFF SEGMENT PUBLIC 'DATA'
- variable5 dw ?
- DATASTUFF ENDS
- ; - - - - - - - - - - - - - - - - - - - -
- MORESTUFFA SEGMENT PUBLIC
- variable61 dw ?
- MORESTUFFA ENDS
- ; - - - - - - - - - - - - - - - - - - - -
- MORESTUFF SEGMENT PUBLIC 'CLASSOF68'
- variable6 dw ?
- MORESTUFF ENDS
- ; - - - - - - - - - - - - - - - - - - - -
- EVENMORESTUFF SEGMENT 'DATA'
- variable7 dw ?
- EVENMORESTUFF ENDS
- ; - - - - - - - - - - - - - - - - - - - -
- CODESTUFF SEGMENT PUBLIC 'CODE'
- ASSUME cs:CODESTUFF, ds:DATASTUFF, ds:NOTDATASTUFF
- ASSUME ds:MORESTUFF,ds:MORESTUFFA, ds:EVENMORESTUFF
- subroutine proc far
- ret
- subroutine endp
- CODESTUFF ENDS
- ; - - - - - - - - - - - - - - - - - - - -
- END
-
-
-
- You will notice that the two CODESTUFFs, the two DATASTUFFs, the
- two MORESTUFFAs and the two STACKSEGs each have the same
- definitions, but that (1) NOTDATASTUFF has a different name than
- DATASTUFF, (2) one MORESTUFF has a different class name from the
- other, (3) one EVENMORESTUFF is PUBLIC and the other is not, and
- (4) the two MORESTUFFAs have NO class name.
-
- Here's the segment information from file1.lst
-
-
-
- N a m e Length Align Combine Class
-
- CODESTUFF . . . . . . . . . . 0005 PARA PUBLIC 'CODE'
- DATASTUFF . . . . . . . . . . 0002 PARA PUBLIC 'DATA'
- EVENMORESTUFF . . . . . . . . 0002 PARA PUBLIC 'DATA'
- MORESTUFF . . . . . . . . . . 0002 PARA PUBLIC 'DATA'
- MORESTUFFA . . . . . . . . . . 0002 PARA PUBLIC
- STACKSEG . . . . . . . . . . . 00C8 PARA STACK 'STACK'
-
-
-
-
- and from file2.lst
-
-
- N a m e Length Align Combine Class
-
- CODESTUFF . . . . . . . 0001 PARA PUBLIC 'CODE'
-
-
-
-
- Chapter 10 - Templates 91
- ______________________
-
- DATASTUFF . . . . . . . 0002 PARA PUBLIC 'DATA'
- EVENMORESTUFF . . . . . 0002 PARA NONE 'DATA'
- MORESTUFF . . . . . . . 0002 PARA PUBLIC 'CLASSOF68'
- MORESTUFFA . . . . . . . 0002 PARA PUBLIC
- NOTDATASTUFF . . . . . . 0002 PARA PUBLIC 'DATA'
- STACKSEG . . . . . . . . 00C8 PARA STACK 'STACK'
-
-
-
- These are in alphabetical order. Before we link them together,
- let's think about what should happen if all three conditions must
- be met. Both CODESTUFF segments are PUBLIC with the same class
- name, so they should merge. Both DATASTUFF segments are PUBLIC
- with the same class name so they should merge. EVENMORESTUFF is
- PUBLIC in one file but not public in the other, so they should
- not merge. MORESTUFF is PUBLIC in both files, but they have
- different class names, so they should not merge. What about
- STACKSEG? The STACK combine type is similar to PUBLIC{1}, and
- they have the same class name, so they should merge. Finally,
- there are the MORESTUFFAs. They have the same name and are
- PUBLIC, but they have no class name. Will they combine?
-
- Let's see what happens. Here is the .MAP file from the command
-
- C> link file1+file2
-
-
- Start Stop Length Name Class
- 00000H 0018FH 00190H STACKSEG STACK
- 00190H 001A1H 00012H MORESTUFFA
- 001B0H 001C1H 00012H DATASTUFF DATA
- 001D0H 001D1H 00002H MORESTUFF DATA
- 001E0H 001E1H 00002H EVENMORESTUFF DATA
- 001F0H 001F1H 00002H NOTDATASTUFF DATA
- 00200H 00201H 00002H EVENMORESTUFF DATA
- 00210H 00220H 00011H CODESTUFF CODE
- 00230H 00231H 00002H MORESTUFF CLASSOF68
-
- Program entry point at 0021:0000
-
-
- STACKSEG, DATASTUFF and CODESTUFF combined. MORESTUFFA combined.
- The others are separate. Doesn't this confuse the linker if it
- has more than one segment with the same name? No. The linker
- knows which variables are in which segments, and the names of the
- segments are not relevant.
-
- If you look at the class information from the linker listing, you
- will notice that all things in the same class are grouped
- together. The linker works from left to right on the command
- line, so for the above, it read file1.obj first and then read
- ____________________
-
- 1 STACK tells the linker to combine any other segments which
- have STACK and the class type 'STACK' and it tells the loader to
- set the SS register to that segment, and set the SP register to
- point to the end of that segment.
-
-
-
-
- The PC Assembler Tutor 92
- ______________________
-
- file2.obj. It orders things (1) first by class (in the order
- encountered, and then (2) by segment (in the order encountered).
- For the linker ordering, a segment is like a subclass.
-
- Look through the assembler files to check that if you link in the
- order file1+file2, the order of encountering classes is 'STACK',
- empty, 'DATA', 'CODE', and 'CLASSOF68'. check the segment
- ordering also. What if we link the opposite way?
-
- > link file2+file1
-
- Here's the listing:
-
-
- Start Stop Length Name Class
- 00000H 0018FH 00190H STACKSEG STACK
- 00190H 00191H 00002H NOTDATASTUFF DATA
- 001A0H 001B1H 00012H DATASTUFF DATA
- 001C0H 001C1H 00002H EVENMORESTUFF DATA
- 001D0H 001D1H 00002H MORESTUFF DATA
- 001E0H 001E1H 00002H EVENMORESTUFF DATA
- 001F0H 00201H 00012H MORESTUFFA
- 00210H 00211H 00002H MORESTUFF CLASSOF68
- 00220H 00234H 00015H CODESTUFF CODE
-
- Program entry point at 0022:0010
-
- Assure yourself that this is the order the classes are
- encountered for file2+file1.
-
-
- Before we go on, let's summarize what we have so far.
-
- 1) In an .asm file, each segment starts with a name followed
- by the word SEGMENT.
-
- 2) Each segment ends with the name followed by the word ENDS
- (end of segment).
-
- This is the minimal segment definition:
-
- ; - - - - -
- SEG_A SEGMENT
-
- SEG_A ENDS
- ; - - - - -
-
- In addition, if you want to combine a segment with segments from
- other files in order to make one large segment, then all the
- segments to be combined must:
-
- 1) have the same name.
- 2) have the same class name (type)
- 3) be declared PUBLIC
-
-
-
-
-
-
-
- Chapter 10 - Templates 93
- ______________________
-
- ASSUME
-
- The next thing from the template file is the word ASSUME. Who is
- assuming what?
-
- ASSUME cs:CODESTUFF, ds:DATASTUFF
-
- This is for the assembler. It says that whenever you are working
- in the CODESTUFF segment, CS will be set to the segment address
- of the CODESTUFF segment. Whenever you are working in the
- DATASTUFF segment, DS will be set to the segment address of the
- DATASTUFF segment. The CS register takes care of itself, but it
- is your responsibility to make sure that DS actually points to
- the proper segment.
-
-
- If you just move a word from memory to a register:
-
- mov cx, variable1
-
- the 8086 automatically thinks that it is in the DS segment. But
- it doesn't have to be that way. The 8086 has something called
- segment overrides. Here is the list:
-
- SEGMENT HEX VALUE
- CS 2E
- DS 3E
- ES 26
- SS 36
-
- An override is a 1 byte machine instruction that tells the 8086
- that for the next instruction, the memory location will not
- reference the natural segment register; what it will reference is
- the segment register named in the override - CS if it is 2Eh, DS
- if it is 3Eh, ES if it is 26h, and SS if it is 36h.
-
- We could plug these in ourselves, but that is a lot of work.
- Fortunately, the assembler takes care of this for us. Let's look
- at the code from the very beginning of the chapter.
-
- ;***********************************
- ; segs.asm
-
- ; - - - - - - - - - - - - -
- STACKSEG SEGMENT STACK 'STACK'
-
- variable4dw 4444h
- dw 100h dup (?)
-
- STACKSEG ENDS
- ; - - - - - - - - - - - - -
- MORESTUFF SEGMENT PUBLIC 'HOKUM'
-
- variable2 dw 2222h
-
- MORESTUFF ENDS
- ; - - - - - - - - - - - - -
-
-
-
-
- The PC Assembler Tutor 94
- ______________________
-
- DATASTUFF SEGMENT PUBLIC 'DATA'
-
- variable1 dw 1111h
-
- DATASTUFF ENDS
- ; - - - - - - - - - - - - -
- CODESTUFF SEGMENT PUBLIC 'CODE'
-
- EXTRN print_num:NEAR , get_num:NEAR
-
- ASSUME cs:CODESTUFF,ds:DATASTUFF
- ASSUME es:MORESTUFF,ss:STACKSEG
-
- variable3 dw 3333h
-
- main proc far
- start: push ds
- sub ax,ax
- push ax
-
- mov ax, DATASTUFF
- mov ds,ax
- mov ax, MORESTUFF
- mov es, ax
-
- mov cx, variable1
- mov variable1, cx
-
- ret
-
- main endp
-
-
- CODESTUFF ENDS
- ; - - - - - - - - - - - -
-
- END start
- ;***************************
-
- For the ASSUME statement we have:
-
- ASSUME cs:CODESTUFF,ds:DATASTUFF
- ASSUME es:MORESTUFF,ss:STACKSEG
-
- What we want to look at is this section of code:
-
- mov cx, variable1
- mov variable1, cx
-
- Here is the listing of the offset address and machine code:
-
-
- 000E 8E C0 mov es,ax
-
- 0010 8B 0E 0000 R mov cx, variable1
- 0014 89 0E 0000 R mov variable1, cx
-
-
-
-
-
- Chapter 10 - Templates 95
- ______________________
-
- 0018 CB ret
-
- Variable1 is in DATASTUFF (ASSUME ds:DATASTUFF), and DS is the
- natural segment for variables. Now let's change the code to:
-
- mov cx, variable2
- mov variable2, cx
-
- This is the ONLY change in the file. Variable2 is in MORESTUFF
- and we have - ASSUME es:MORESTUFF. Here's the listing when we
- assemble the modified file.
-
- 000E 8E C0 mov es,ax
-
- 0010 26: 8B 0E 0000 R mov cx, variable2
- 0015 26: 89 0E 0000 R mov variable2, cx
-
- 001A CB ret
-
- The assembler has put 26h as a segment override. When the 8086
- looks at the machine code, it knows that those two instructions
- reference the es, not the ds, segment register. Also note that
- the code is now two bytes longer - one byte for each segment
- override. The "ret" instruction is at 1Ah (26d) instead of 18h
- (24d).
-
- Let's try it with:
-
- mov cx, variable3
- mov variable3, cx
-
- Variable3 is in CODESTUFF and we have - ASSUME cs:CODESTUFF.
- Here's the listing:
-
- 000E 8E C0 mov es,ax
-
- 0010 2E: 8B 0E 0000 R mov cx, variable3
- 0015 2E: 89 0E 0000 R mov variable3, cx
-
- 001A CB ret
-
- The assembler put in the CS segment override. Now the 8086 knows
- that variable3 is in the CS segment. Finally:
-
- mov cx, varaible4
- mov variable4, cx
-
- Variable4 is in STACKSEG and we have - ASSUME ss:STACKSEG. Here's
- the listing:
-
- 000E 8E C0 mov es,ax
-
- 0010 36: 8B 0E 0000 R mov cx, variable4
- 0015 36: 89 0E 0000 R mov variable4, cx
-
- 001A CB ret
-
-
-
-
-
- The PC Assembler Tutor 96
- ______________________
-
- Once again, the assembler put in a segment override. This time it
- was the SS override.
-
- That's nifty. We simply tell the assembler which segment register
- we will use for each segment and it does all the work. We will do
- more with segment overrides in the chapter on addressing modes.
-
- Remember, though, that it is your responsibility to see that at
- the time this code is used, the segment register actually
- contains the appropriate segment address.
-
- Is this ASSUME definition unique? That is, must there be a one to
- one correspondence between segments and registers, with each
- segment having its own register? No, not at all. Here are a two
- ASSUME statements, both of which are legal:
-
- ASSUME cs:COMSEG, ds:COMSEG, es:COMSEG, SS:COMSEG
-
- All four registers contain the address of the same segment. In
- fact, we will meet this statement when we talk about COM files.
- This is the only appropriate statement for a .COM file
-
- ASSUME ds:SEG_A, ds:SEG_B, es:SEG_C, es:SEG_D, es:SEG_A
-
- Four different segments, two of which are referenced by DS and
- three of which are referenced by ES. Remember, ASSUME tells the
- assembler that whenever you access something in that segment, the
- named register will be set to the starting segment address. What
- exactly does this mean to the assembler? Let's rearrange this a
- little:
-
- SEG_A ds, es
- SEG_B ds
- SEG_C es
- SEG_D es
-
- This is the list from the assembler's viewpoint. Suppose it has a
- variable that is in SEG_C. Does it need an override? Yes, it
- needs an ES override. Suppose it has a variable in SEG_A. Does
- it need an override? No, because DS is set to that segment.
-
-
-
- SUBROUTINES
-
- In assembler parlance, subroutines are called procedures. Why?
- You got me. In any case, whenever I say subroutine, process,
- subprogram, or anything like that, I mean a procedure. A
- procedure can have any name you want. You start a procedure by
- giving the name, using the reserved word 'proc' and then
- defining it as either near or far.
-
- my_procedure proc near
-
- is a near procedure with the name my_procedure. You end a
- procedure by giving the name and following it with the reserved
- word 'endp' (for end of procedure).
-
-
-
-
- Chapter 10 - Templates 97
- ______________________
-
-
- my_procedure endp
-
- What is a near procedure? It is one which is ALWAYS in the same
- segment as the calling program. When you call a near procedure,
- the value in CS stays the same, but IP (the instruction pointer)
- changes to the offset of the first byte of the procedure. The
- next instruction executed will be the first byte of the
- procedure.
-
- If a procedure is called even once from a different segment, then
- it MUST be a far procedure.
-
- my_procedure proc far
-
- my_procedure endp
-
- When you call a far procedure, the CS register is changed to the
- segment of the called procedure and IP (the instruction pointer)
- is set to the first byte of the procedure. This will be covered
- in the chapter on subroutines.
-
- How does the loader know where to start the program? The
- assembler tells the linker which tells the loader. How does the
- assembler know? You tell it. The last line of the file is the
- single word 'END'. That tells the assembler that you are done
- with the assembler code. If there is a word after the word 'END'
- (on the same line), then the assembler assumes that this word is
- the name of the label where the program starts. The first
- instruction executed will be whatever immediately follows that
- label. In the template files we have:
-
- END start
-
- so the label 'start:' indicates where the first instruction is.
- For an .EXE file, this can be anywhere at all, but we have it at
- the beginning. The label 'start:' is used for clarity, but we
- could just as easily have had:
-
- END zzyx4
-
- The assembler would then look for the label 'zzyx4:' as the place
- to start the program. If you look at the link .MAP file from our
- file1+file2 example you will see:
-
- Program entry point at 0021:0000
-
- That says that the starting address is CS = 0021h, IP = 0000h.
- Note that both CS and IP are different for the file2+file1
- example:
-
- Program entry point at 0022:0010
-
- where CS = 0022h and IP = 0010h. The initial offset was given to
- the linker by the assembler. The linker did any adjustment to the
- offset if it moved the code, and then it calculated the segment
- address itself.
-
-
-
-
- The PC Assembler Tutor 98
- ______________________
-
-
-
- RET
-
- When the loader loads the program, it puts the segment of the
- starting address in CS and the offset of the starting address in
- IP. This gives control to your program. When your program is
- done, how does it get back to the operating system? Good
- question.
-
- When the loader loads the program, it creates something called
- the PSP (program segment prefix). This is a 100h (256d) byte
- block of information and code. The first byte (offset 0000) of
- this block is an 8086 instruction for an orderly exit from a
- program. What we need to do is set CS to the PSP segment and set
- IP to 0000. Then the next instruction executed will be the
- orderly exit code.
-
- In talking about procedures, I said that when you call a far
- procedure, the 8086 puts the procedure's segment in CS and the
- procedure's offset in IP. But before that, it does two things:
-
- push CS ; these are the old CS and IP
- push IP ; this is not a real 8086 instruction {2}
-
- When you have a RET (return) instruction in a far procedure, the
- 8086 does the following:
-
- pop IP ; this is not a real 8086 instruction
- pop CS ; put back the old CS and IP
-
- so RET resets CS and IP to go back where it came from. That is
- its job.
-
- What has been pushed on the stack before starting your program?
- NOTHING. That's right. That means that if you execute
-
- ret
-
- at the end of your program, the 8086 will pop two pieces of
- garbage into IP and CS.
-
- Fortunately, when setting up a program, the loader ALWAYS puts
- the segment address of the PSP in DS., the data segment. All we
- need to do is PUSH DS (the PSP) and then PUSH 0 (offset 0000) and
- we have the address of our orderly exit code. If we then execute
- RET, it will POP these two items into IP and CS, sending us to
- our orderly exit code. That is what is at the beginning of the
- code section of the template file. We cannot PUSH a constant, so
- we manufacture a 0 with 'sub ax, ax'. The code is:
-
- push ds ; PSP segment
- sub ax, ax ; manufacture a 0
- ____________________
-
- 2 This is not actual 8086 code. You have no direct access to
- IP. This is, however, what the 8086 effectively does.
-
-
-
-
- Chapter 10 - Templates 99
- ______________________
-
- push ax ; offset = 0000
-
- and the program is set up for the return.
-
- That's a lot of things together, so let's review. To exit a
- procedure we use RET, but for the starting procedure we need to
- return to the operating system. The PSP has the code for an
- orderly return at offset 0000. At load time, the loader puts the
- segment address of the PSP in DS. We push the PSP segment address
- and offset 0000 for later use by the RET instruction. We do this
- with:
-
- push ds ; PSP segment
- sub ax, ax ; manufacture a 0
- push ax ; offset = 0000
-
- These should be the first instructions in the program.
-
- Now that you have stored the PSP, DS is free for other use. You
- can now use DS to hold the segment address of your data. DS is
- used because that is the segment register that the 8086 expects
- unless told otherwise. You can't move a constant to a segment
- register, so this is a two step process:
-
- mov ax, DATASTUFF
- mov ds, ax
-
-
- EXTRN
-
- Finally, an EXTRN statement tells the assembler that the
- procedure or data is in another file and you did not forget it.
- For a procedure, you need to say whether it is NEAR (push old IP
- and put in new IP) or far (push old CS and IP; put in new CS and
- IP). Here is the assembler listing for five calls:
-
- E8 09CA R call near_routine
- 9A 15EE ---- R call far_routine
- E8 0000 E call near_external_routine
- 9A 0000 ---- E call far_external_routine
- E8 0000 E call get_unsigned
-
- The first two are in the same file, the next two are in an
- external file, and we have our friend 'get_unsigned'. 'R' means
- that the data may be changed, 'E' means that it is external, and
- will be done by the linker. The first four are labelled whether
- they are near or far. 'get_unsigned' is a near procedure. Notice
- that E8 is the near call while 9A is the far call. Also notice
- that the assembler reserves one word for the new IP in the near
- calls. If the call is in the same file, the assembler fills in
- this number, but if it is external the assembler sets it to 0. In
- the far calls the assembler reserves two words instead of one.
- The first word is again the new IP, which is either filled in or
- set to zero. The second word is for the segment address, and will
- be set by the linker.
-
-
-
-
-
-
- The PC Assembler Tutor 100
- ______________________
-
- Whew!!! It sure took a long time to go through all that and you
- still probably are unsure about some of this. Read the summary,
- and if you don't feel good about it, leave it for a day or two
- and reread it then.
-
- At the end of the book I will show you how you can simplify a lot
- of these things by using standardized segment names and some
- other standardized instructions. For now, you need to get used to
- what the structure of programs is, and we will continue using the
- same type of templates.{3}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ____________________
-
- 3 Just think of me as the computer equivalent of a woodshop
- teacher who forces you to use hand tools to make a coffee table
- rather than allowing you to use what you really want to be
- using - a chainsaw.
-
-
-
-
- Chapter 10 - Templates 101
- ______________________
-
-
- SUMMARY
-
- SEGMENTS
-
- Segments are defined by giving a name followed by the word
- SEGMENT. The end of a segment is signalled by the segment name,
- followed by the word ENDS (end of segment).
-
- ; - - - - -
- SOME_NAME SEGMENT
-
- SOME_NAME ENDS
- ; - - - - -
-
- (As always, anything after a comma is a comment and is ignored by
- the assembler). In addition, if you want to combine a segment
- with other segments, then all the segments to be combined must:
-
- 1) have the same name.
- 2) have the same type (class)
- 3) be declared PUBLIC
-
-
- THE STACK SEGMENT
-
- The stack segment may have any name you want, but should be
- declared " SEGMENT STACK 'STACK' ". This forces the loader to do
- certain initialization for you. If you don't declare it this way,
- you have to do the initialization yourself.
-
- ANY_NAME SEGMENT STACK 'STACK'
-
-
- EXTRN
-
- For procedures, an EXTRN statement tells the assembler that the
- procedure that you want to call is in a different file, that you
- didn't forget it. Procedures which are EXTRN must be declared
- either NEAR or FAR. The grammar is name colon NEAR or name colon
- FAR.
-
- EXTRN procedure1:NEAR, procedure2:FAR
-
- You may declare as many things on one line as will fit, but you
- need to separate them with commas. There can be no comma at the
- end.
-
-
- ASSUME
-
- An ASSUME statement tells the assembler that when a statement
- references that particular segment, the corresponding segment
- register will be set to that segment address.
-
- ASSUME es:MORESTUFF
-
-
-
-
-
- The PC Assembler Tutor 102
- ______________________
-
- tells the assembler that no matter what you do in other parts of
- the program, every time a variable in MORESTUFF is referenced, es
- will have the segment address of MORESTUFF. This is for the
- purpose of correct coding of segment overrides.
-
-
- SEGMENT OVERRIDES
-
- Normally, when the 8086 accesses a variable in memory, it does so
- via the DS segment register. This can be changed with a segment
- override. The assembler puts the correct segment override code in
- front of the instruction and the 8086 will use that segment
- register to access the data in memory. The override codes are:
-
- SEGMENT HEX VALUE
- CS 2E
- DS 3E
- ES 26
- SS 36
-
-
- CS
-
- CS is the code segment. When the 8086 processes machine code, it
- ALWAYS uses CS. There is no override.
-
-
- IP
-
- IP, the instruction pointer, gives the offset in CS of the next
- instruction to be processed. When the 8086 processes an
- instruction, it looks at IP, gets the next instruction and
- updates IP. This is totally automatic and internal to the 8086.
- You have no direct access to IP.
-
-
- PROCEDURES
-
- A procedure is declared by giving a name followed by the word
- 'proc' followed by either NEAR or FAR. A procedure is ended by
- giving the name, followed by 'endp' (end of procedure).
-
- ; - - - - -
- square_root proc far
-
- square_root endp
- ; - - - - -
-
- The words NEAR and FAR are for the assembler and the linker so
- they know whether to change just IP or both IP and CS in RET, the
- return statement as well as in CALL, the subroutine call.
-
-
- RET
-
- The assembler codes a near or a far return depending on whether
- you have declared a near or a far procedure. A NEAR return POPs
-
-
-
-
- Chapter 10 - Templates 103
- ______________________
-
- IP off of the stack while a FAR return POPs IP then POPs CS.
- Thus, a NEAR return stays in the same segment but a FAR return
- gets a new segment address in CS.{4}
-
-
- END
-
- The word END signals to the assembler that you are done with
- code. The assembler will ignore all following lines, whether they
- are blank or contain code.
-
- If the line with END has a name after the word END, then the
- assembler assumes that this is the name of a label where
- execution will begin at run time. That means that the instruction
- at 'label:' will be the first instruction executed in the
- program.
-
-
- SETUP
-
- In order to setup the program in the beginning you need to (1)
- PUSH the segment address of the PSP (which is in DS), then push 0
- (the offset of the orderly return code). Following this you need
- to put the segment address of the data segment in DS. The code
- for all of this is:
-
- push ds ; PSP seg address is in ds
- sub, ax, ax ; 0
- push ax ; push 0000 offset
-
- mov ax, DATA_SEG ; data segment address to ds
- mov ds, ax
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ____________________
-
- 4 Of course, it is possible for CS to keep the same value if
- the calling procedure is is the same segment.
-
-